package com.msb.juc.c_026;

import java.io.IOException;
import java.sql.Time;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class T05_HelloThreadPool {
    static class Task implements Runnable {

        private int i;

        public Task(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " Task " + i);
            // 每个任务都会阻塞在这里
            try {
                System.in.read();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public String toString() {
            final StringBuffer sb = new StringBuffer("Task{");
            sb.append("i=").append(i);
            sb.append('}');
            return sb.toString();
        }
    }

    public static void main(String[] args) {
        /*
        定义线程池
        corePoolSize：核心线程数，初始的线程数量
        maximumPoolSize：最大线程数，扩展后的最大线程数量
        keepAliveTime：线程的最大生存时间，线程池中核心线程之外的线程在空闲后归还给操作系统
        unit：生存时间单位
        workQueue：任务队列，各种BlockingQueue
        threadFactory：线程工厂，制造线程，可以自定义线程工厂，实现ThreadFactory接口即可
        handler：拒绝策略，当线程忙并且任务队列已满，就需要执行拒绝策略，可以自定义，JDK默认提供4种
            Abort：抛异常
            Discard：扔掉，不抛异常
            DiscardOldest：扔掉排队时间最久的
            CallerRuns：调用者处理任务，哪个线程提交的任务，哪个线程执行
            实际上，基本是自定义策略，实现相应接口
        */
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4,
                60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(4),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());

        for (int i = 0; i < 8; i++) {
            tpe.execute(new Task(i));
        }

        // 获取队列中的任务，0和1被核心线程处理了，所以不会打印
        System.out.println(tpe.getQueue());
        tpe.execute(new Task(100));
        System.out.println(tpe.getQueue());
        tpe.shutdown();
    }
}
